<script lang="ts">
	import Draggable from '$lib/components/Feedback/Draggable/Draggable.svelte';
	import Divider from '$lib/components/Basic/Divider/Divider.svelte';
	import Icon from '$lib/components/Basic/Icon/Icon.svelte';
	import { onMount, onDestroy, tick } from 'svelte';
	import { throttle } from 'lodash-es';
	import { page } from '$app/state';
	import { type Option } from '$lib/components/Basic/Popover/types';
	import { goto } from '$app/navigation';
	import PopoverSlot from '$lib/components/Basic/Popover/PopoverSlot.svelte';
	import { ensurePortalContainer } from '$lib/utils/container/ensurePortalContainer';
	import Portal from 'svelte-portal';
	import { contentRefreshStore } from '$lib/stores/refreshContent';
	import RectButton from '$lib/components/Basic/Button/RectButton.svelte';

	// 定义类型接口
	interface NavItem {
		id: number;
		name: string;
		path: string;
		sort: number;
		isActive: boolean;
		x: number;
		y: number;
		width: number;
		height: number;
	}
	interface DragItems {
		name: string;
		path: string;
	}

	// 响应式状态（仅保留需要响应式追踪的变量）
	let navItems = $state<NavItem[]>([]); // 影响UI渲染，必须响应式
	let navItemsRef = $state<HTMLElement | null>(null); // 绑定DOM，影响初始化逻辑
	let itemRefs = $state<(HTMLElement | null)[]>([]); // 绑定子元素，影响初始位置计算
	// 组件内计数器
	let localIdCounter = 0;
	let isInit = false;
	let dragItems: DragItems[] = [];

	// 新增：滚动相关状态
	let scrollOffset = $state(0); // 滚动偏移量
	let showLeftArrow = $state(false); // 左侧箭头显示状态
	let showRightArrow = $state(false); // 右侧箭头显示状态
	let totalWidth = $state(0); // 所有导航项总宽度
	let activeSortValue = $state(0); // 影响激活状态显示
	let hoverSortValue = $state(0); // 影响激活状态显示
	let isDragging = $state(false);
	const stablePath = $derived(page.url.pathname);
	let lastProcessedPath = ''; // 新增：路径快照
	// 新增：滚动步长（每次点击箭头滚动的距离）
	const SCROLL_STEP = 150;

	// 非响应式变量（无需追踪，不影响UI）
	const currentPosition = { x: 0, y: 0 }; // 拖拽位置，影响navItems.x
	let currentSort = 0; // 拖拽排序逻辑，影响交换判断
	let currentIndexR = -1; // 右侧项索引，影响交换逻辑
	let currentIndexL = -1; // 左侧项索引，影响交换逻辑
	let isChange = true; // 交换状态标记，影响拖拽逻辑
	let observer: ResizeObserver;

	// 右键菜单
	let clickNavIndex: number | null = $state(null);
	let triggerRect: {
		top: number;
		left: number;
		bottom: number;
		right: number;
		width: number;
		height: number;
	} = {
		top: 0,
		left: 0,
		bottom: 0,
		right: 0,
		width: 0,
		height: 0
	};
	let popoverSlotRef: HTMLElement | undefined = $state();
	let portalContainer: HTMLElement | undefined = $state();
	let popover: PopoverSlot | null = $state(null); // 绑定组件实例
	// 生成局部唯一 ID
	const generateLocalId = () => {
		localIdCounter++;
		return localIdCounter; // 如 local-1、local-2...
	};

	// 计算初始位置
	const initialNavPositions = async () => {
		isInit = false;
		// 从localstore中获取相关数据
		const str = localStorage.getItem('savedNavItems');
		const arr: NavItem[] = str && str != '[]' ? JSON.parse(str) : [];
		arr.sort((a, b) => a.sort - b.sort);
		dragItems = arr.map((item) => ({
			name: item.name,
			path: item.path
		}));
		let targetIndex = dragItems.findIndex((item) => item.path === page.url.pathname);
		if (targetIndex < 0) {
			dragItems.push({
				name: getMenuNameByUrl(page.data.menuItems, page.url.pathname),
				path: page.url.pathname
			});
			targetIndex = dragItems.length - 1;
		}
		// 初始化navItems
		navItems = dragItems.map((item, index) => ({
			...item,
			id: generateLocalId(),
			sort: index + 1,
			isActive: index === targetIndex ? true : false,
			x: 0,
			y: 0,
			width: 0,
			height: 0
		}));
		activeSortValue = targetIndex + 1;
		await new Promise((resolve) => setTimeout(resolve, 0));
		if (itemRefs.length === 0 || !navItemsRef) return;

		let currentX = 0;
		const baseY = 0;
		totalWidth = 0; // 重置总宽度

		for (let i = 0; i < itemRefs.length; i++) {
			const itemEl = itemRefs[i];
			if (!itemEl) return;

			const itemWidth = itemEl.offsetWidth - 1;
			navItems[i].x = currentX;
			navItems[i].y = baseY;
			navItems[i].width = itemWidth;
			navItems[i].height = 30;

			currentX += itemWidth;
			totalWidth += itemWidth; // 累加总宽度
		}
		const containerWidth = navItemsRef.offsetWidth;
		if (navItems[targetIndex].x + navItems[targetIndex].width > containerWidth + scrollOffset) {
			scrollOffset = navItems[targetIndex].x + navItems[targetIndex].width - containerWidth;
		} else if (navItems[targetIndex].x < scrollOffset) {
			scrollOffset = navItems[targetIndex].x;
		}
		// 检查是否需要显示箭头
		checkScrollArrows();
		saveNavItems();
		lastProcessedPath = page.url.pathname;
		isInit = true;
	};

	// 新增：检查箭头显示状态
	const checkScrollArrows = () => {
		if (!navItemsRef) return;

		const containerWidth = navItemsRef.offsetWidth;
		// 总宽度大于容器宽度时才可能需要显示箭头
		// const canScroll = totalWidth > containerWidth;

		// 右侧箭头：还有可滚动空间时显示
		showRightArrow = scrollOffset + containerWidth < totalWidth;
		// 左侧箭头：已经滚动过（偏移量>0）时显示
		showLeftArrow = scrollOffset > 0;
	};
	// 新增：滚动到指定偏移量
	const scrollToOffset = (offset: number) => {
		if (!navItemsRef) return;
		const containerWidth = navItemsRef.offsetWidth;

		// 限制偏移量范围
		const maxOffset = Math.max(0, totalWidth - containerWidth);
		scrollOffset = Math.max(0, Math.min(offset, maxOffset));

		// 更新箭头显示状态
		checkScrollArrows();
	};

	// 新增：向左滚动
	const scrollLeft = () => {	
		scrollToOffset(scrollOffset - SCROLL_STEP);
	};

	// 新增：向右滚动
	const scrollRight = () => {
		scrollToOffset(scrollOffset + SCROLL_STEP);
	};
	// 关闭标签
	const closeNav = async (index: number) => {
		if (index === 0 && navItems.length === 1) {
			navItems.length = 0;
			goto('/home');
			if (lastProcessedPath === '/home') {
				getNavItemByUrl(stablePath);
			}
			return;
		}
		const closeSort = navItems[index].sort;
		const closeActive = navItems[index].isActive;
		const closeWidth = navItems[index].width;
		const moveItems = navItems.filter((item) => item.sort > closeSort);

		navItems.splice(index, 1);
		totalWidth -= closeWidth;
		if (closeActive) {
			if (moveItems.length > 0) {
				moveItems.forEach((item) => {
					if (item.sort === closeSort + 1) {
						// activeSortValue = closeSort;
						// item.isActive = true;
						goto(item.path);
					}
					item.sort--;
					item.x -= closeWidth;
				});
			} else {
				if (navItems.length > 0) {
					const target = navItems.find((item) => item.sort === closeSort - 1);
					if (target) {
						// target.isActive = true;
						goto(target.path);
						// activeSortValue = closeSort - 1;
					}
				} else {
					activeSortValue = 0;
				}
			}
		} else {
			moveItems.forEach((item) => {
				item.sort--;
				item.x -= closeWidth;
			});
			activeSortValue = closeSort - 1;
		}
		checkScrollArrows();
		// 移除navLength，直接使用navItems.length
		saveNavItems();
	};

	// 保存菜单
	const saveNavItems = () => {
		localStorage.setItem('savedNavItems', JSON.stringify(navItems));
	};

	// 处理容器大小变化
	const handleResize = throttle(() => {
		if (!navItemsRef) return;
		checkScrollArrows();
	}, 60);

	// 初始化与清理逻辑
	onMount(() => {
		portalContainer = ensurePortalContainer('popovers-container');
		// 计算初始位置
		initialNavPositions();
		observer = new ResizeObserver(handleResize);
		if (navItemsRef) {
			observer.observe(navItemsRef);
		}
	});

	// 生命周期：卸载时
	onDestroy(() => {
		if (navItemsRef) {
			observer.unobserve(navItemsRef);
		}
	});
	function getMenuNameByUrl(options: Option[], path: string): string {
		for (const option of options) {
			if (option.code === path) {
				return option.name;
			}
			if (option.children && option.children.length > 0) {
				const result = getMenuNameByUrl(option.children, path);
				if (result && result != '') {
					return result;
				}
			}
		}
		return '';
	}

	async function getNavItemByUrl(path: string) {
		if (!navItemsRef) return;
		const target = navItems.find((item) => item.path === path);
		const count = navItems.length;
		const containerWidth = navItemsRef.offsetWidth;
		if (target) {
			if (target.isActive === true) return;
			navItems.forEach((item) => {
				item.isActive = false;
			});
			target.isActive = true;
			activeSortValue = target.sort;
			// 滚动条位置设置
			if (target.x + target.width > containerWidth + scrollOffset) {
				scrollOffset = target.x + target.width - containerWidth;
			} else if (target.x < scrollOffset) {
				scrollOffset = target.x;
			}
		} else {
			const maxTarget = navItems.find((item) => item.sort === count);
			let newX = 0;
			if (maxTarget) {
				newX = maxTarget.x + maxTarget.width - 1;
			} else {
				newX;
			}
			navItems.forEach((item) => {
				item.isActive = false;
			});
			navItems.push({
				name: getMenuNameByUrl(page.data.menuItems, path),
				path: path,
				id: generateLocalId(),
				sort: count + 1,
				isActive: true,
				x: newX,
				y: 0,
				width: 0,
				height: 30
			});
			activeSortValue = count + 1;
			await tick();
			const newItemEl = itemRefs[count];
			if (!newItemEl) return; // 若DOM未加载完成，跳过
			const newItemWidth = newItemEl.offsetWidth - 1;
			navItems[count].width = newItemWidth;
			totalWidth += newItemWidth;
			scrollOffset = Math.max(0, totalWidth - containerWidth);
			saveNavItems();
		}
		checkScrollArrows();		
	}

	$effect(() => {
		if (stablePath !== lastProcessedPath && isInit) {
			getNavItemByUrl(stablePath);
			lastProcessedPath = stablePath; // 更新快照
		}
		// getNavItemByUrl(page.url.pathname); // 当 count 变化时执行
	});

	// 拖拽开始
	const startMove = (index: number, startPosition: { x: number; y: number }) => {
		isDragging = true;
		hoverSortValue = 0;
		currentPosition.x = startPosition.x;
		isChange = true;
		goto(navItems[index].path);
	};

	// 拖拽中
	const onMoving = (index: number, toPosition: { x: number; y: number }) => {
		navItems[index].x = toPosition.x;
		if (isChange) {
			currentSort = navItems[index].sort;
			currentIndexR = navItems.findIndex((item) => item.sort === currentSort + 1);
			currentIndexL = navItems.findIndex((item) => item.sort === currentSort - 1);
			activeSortValue = currentSort;
			isChange = false;
		}

		// 向右交换
		if (
			!isChange &&
			currentIndexR !== -1 &&
			toPosition.x + navItems[index].width >
				navItems[currentIndexR].x + navItems[currentIndexR].width / 2
		) {
			[navItems[index].sort, navItems[currentIndexR].sort] = [
				navItems[currentIndexR].sort,
				navItems[index].sort
			];
			const tempX = currentPosition.x;
			currentPosition.x =
				navItems[currentIndexR].x - navItems[index].width + navItems[currentIndexR].width;
			navItems[currentIndexR].x = tempX;
			isChange = true;
		}

		// 向左交换
		if (
			!isChange &&
			currentIndexL !== -1 &&
			toPosition.x < navItems[currentIndexL].x + navItems[currentIndexL].width / 2
		) {
			[navItems[index].sort, navItems[currentIndexL].sort] = [
				navItems[currentIndexL].sort,
				navItems[index].sort
			];
			currentPosition.x = navItems[currentIndexL].x;
			navItems[currentIndexL].x = navItems[currentIndexL].x + navItems[index].width;
			isChange = true;
		}
	};

	// 拖拽结束
	const endMove = (index: number) => {
		navItems[index].x = currentPosition.x;
		isDragging = false;
		saveNavItems();
	};

	// 打开右键菜单
	const openNavMenu = async (index: number, event: Event) => {
		event.preventDefault();
		const mouseEvent = event as unknown as MouseEvent;
		triggerRect.left = mouseEvent.clientX;
		triggerRect.top = mouseEvent.clientY;
		triggerRect.right = mouseEvent.clientX;
		triggerRect.bottom = mouseEvent.clientY;
		if (clickNavIndex === null) {
			clickNavIndex = index;
			document.addEventListener('click', outNavClick, true);
		} else {
			if (!popover) return;
			popover.calculatePosition();
		}
	};

	// 关闭右键菜单
	const closeNavMenu = () => {
		clickNavIndex = null;
		document.removeEventListener('click', outNavClick, true);
	};

	// 关闭当前标签
	const closeCurrent = () => {
		if (clickNavIndex !== null) {
			closeNav(clickNavIndex);
			closeNavMenu();
		}
	};

	// 关闭右侧标签
	const closeRight = () => {
		if (clickNavIndex !== null) {
			const clickSort = navItems[clickNavIndex].sort;
			const filtered = navItems.filter((item) => item.sort <= clickSort);
			navItems.splice(0, navItems.length, ...filtered);
			closeNavMenu();

			if (!navItems.some((item) => item.isActive)) {
				const target = navItems.find((item) => item.sort === clickSort);
				if (target) goto(target.path);
			}
			saveNavItems();
		}
	};

	// 关闭左侧标签
	const closeLeft = () => {
		if (clickNavIndex !== null) {
			const clickSort = navItems[clickNavIndex].sort;
			const xSum = navItems[clickNavIndex].x;

			const filtered = navItems
				.filter((item) => item.sort >= clickSort)
				.map((item) => ({
					...item, // 复制原项目所有属性
					sort: item.sort - clickSort, // sort 减去 clickSort
					x: item.x - xSum // x 减去小于 clickSort 的 x 总和
				}));

			navItems.splice(0, navItems.length, ...filtered);

			closeNavMenu();

			if (!navItems.some((item) => item.isActive)) {
				const target = navItems.find((item) => item.sort === 1);
				if (target) goto(target.path);
			} else {
				activeSortValue -= clickSort - 1;
			}
			saveNavItems();
		}
	};

	// 关闭其他标签
	const closeOther = () => {
		if (clickNavIndex !== null) {
			const clickItem = navItems[clickNavIndex];
			navItems.splice(0, navItems.length, { ...clickItem, sort: 1, x: 0 });
			closeNavMenu();
			goto(navItems[0].path);
			saveNavItems();
		}
	};

	// 关闭所有标签
	const closeAll = () => {
		navItems.length = 0;
		goto('/home');				
		closeNavMenu();
		if (lastProcessedPath === '/home') {
			// console.log('执行closeAll')
			getNavItemByUrl(stablePath);
		}
	};

	// 点击外部关闭右键菜单
	const outNavClick = (e: MouseEvent) => {
		if (popoverSlotRef && !popoverSlotRef.contains(e.target as Node)) {
			closeNavMenu();
		}
	};

	// 在新窗口打开
	const openInNewWindow = () => {
		if (clickNavIndex !== null) {
			window.open(`${page.url.origin}${navItems[clickNavIndex].path}`, '_blank');
			closeNavMenu();
		}
	};

	// 重新加载
	const refresh = () => {
		$contentRefreshStore.refreshContent();
		closeNavMenu();
	};

	const reload = () => {
		if (clickNavIndex !== null) {
			window.location.href = navItems[clickNavIndex].path;
			closeNavMenu();
		}
	};
</script>

<!-- 模板与样式保持不变 -->
<div class="nav-container">
	<!-- 左侧滚动箭头 -->
	<div
		class="nav-tool tool-item"
		class:hiddenshadow={navItems.length === 0}
		class:disabled={!showLeftArrow}
		onclick={scrollLeft}
		aria-label="向左滚动"
		onkeydown={() => {}}
		role="button"
		tabindex="0"
	>
		<Icon src="symbol/arrow-left-round" size="20"></Icon>
	</div>
	<div class="nav-group">
		<div
			class="nav-items"
			bind:this={navItemsRef}
			style={`transform: translateX(${-scrollOffset}px);`}
		>
			{#each navItems as item, index (item.id)}
				<Draggable
					bind:parentRef={navItemsRef}
					{index}
					x={item.x}
					y={item.y}
					isActive={item.isActive}
					axis="x"
					{startMove}
					{onMoving}
					{endMove}
				>
					<div
						class="drag_window"
						class:isActive={item.isActive}
						class:isInactive={!item.isActive}
						bind:this={itemRefs[index]}
						role="button"
						aria-haspopup="true"
						tabindex="0"
						oncontextmenu={(e) => openNavMenu(index, e)}
					>
						<div
							class="boder-item"
							class:hiddenLine={item.sort === 1 ||
								item.sort === activeSortValue + 1 ||
								item.sort === activeSortValue ||
								item.sort === hoverSortValue ||
								item.sort === hoverSortValue + 1}
						>
							<Divider direction="vertical"></Divider>
						</div>
						<div
							class="drag-content"
							onmouseenter={() => {
								if (!isDragging) {
									hoverSortValue = item.sort;
								}
							}}
							onmouseleave={() => {
								if (!isDragging) {
									hoverSortValue = 0;
								}
							}}
							onkeydown={() => {}}
							role="button"
							tabindex="0"
						>
							<div class="drag_title">{item.name}</div>
							<div
								class="drag_close"
								onclick={() => closeNav(index)}
								onmousedown={(e) => e.stopPropagation()}
								onkeydown={() => {}}
								role="button"
								tabindex="0"
							>
								<Icon src="symbol/close" size="14"></Icon>
							</div>
						</div>
						<div
							class="boder-item"
							class:hiddenLine={item.sort === navItems.length ||
								item.sort === activeSortValue - 1 ||
								item.sort === activeSortValue ||
								item.sort === hoverSortValue ||
								item.sort === hoverSortValue - 1}
						>
							<Divider direction="vertical"></Divider>
						</div>
					</div>
				</Draggable>
			{/each}
		</div>
	</div>
	<!-- 右侧滚动箭头 -->
	<div class="nav-tool" class:hiddenshadow={!showRightArrow}>
		<div
			class="tool-item"
			class:disabled={!showRightArrow}
			onclick={scrollRight}
			onkeydown={() => {}}
			aria-label="向右滚动"
			role="button"
			tabindex="0"
		>
			<Icon src="symbol/arrow-right-round" size="20"></Icon>
		</div>
		<RectButton icon="symbol/refresh" type="text" onClick={refresh} iconSize={20} style="padding: 4px;"
		></RectButton>
	</div>
</div>
<!-- 右键菜单 -->
{#if clickNavIndex !== null}
	<Portal target={portalContainer}>
		<div class="rcMenu-container">
			<PopoverSlot {triggerRect} bind:this={popover} bind:popoverRef={popoverSlotRef}>
				<div class="rcNavMenu">
					<ul>
						<li class="menuList">
							<div onclick={openInNewWindow} onkeydown={() => {}} role="button" tabindex="0">
								在新窗口打开
							</div>
						</li>
						<li class="menuList">
							<div onclick={reload} onkeydown={() => {}} role="button" tabindex="0">
								<span>重新加载</span>
								<span style="margin-left: 176px;">F5</span>
							</div>
						</li>
						<Divider margin="10px" style="dashed"></Divider>
						<li>
							<div
								class="menuList"
								onclick={closeCurrent}
								style="width: 150px;"
								onkeydown={() => {}}
								role="button"
								tabindex="0"
							>
								关闭当前
							</div>
							<div class="divider--vertical">
								<Divider direction="vertical"></Divider>
							</div>
							<div
								class="menuList"
								onclick={closeLeft}
								onkeydown={() => {}}
								role="button"
								tabindex="0"
								style="width:46px"
							>
								左侧
							</div>
							<div class="divider--vertical">
								<Divider direction="vertical"></Divider>
							</div>
							<div
								class="menuList"
								onclick={closeRight}
								onkeydown={() => {}}
								role="button"
								tabindex="0"
								style="width:46px"
							>
								右侧
							</div>
						</li>
						<li class="menuList">
							<div onclick={closeOther} onkeydown={() => {}} role="button" tabindex="0">
								关闭其他
							</div>
						</li>
						<li class="menuList">
							<div onclick={closeAll} onkeydown={() => {}} role="button" tabindex="0">关闭全部</div>
						</li>
					</ul>
				</div>
			</PopoverSlot>
		</div>
	</Portal>
{/if}

<style lang="scss">
	.nav-container {
		position: relative;
		display: flex;
		width: 100%;
		height: 30px;
		overflow: hidden; // 隐藏超出容器的内容
	}
	.nav-tool {
		z-index: 1;
		padding: 0 8px;
		flex-shrink: 0;
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 8px;
		box-shadow: 0 0 5px 0 var(--color-shadow);
	}
	.nav-tool.hiddenshadow {
		box-shadow: none;
	}
	.tool-item {
		cursor: pointer;
		color: var(--color-info-800);
	}
	.tool-item.disabled {
		cursor: not-allowed;
		color: var(--color-info-400);		
	}
	.nav-group {
		position: relative;
		flex: 1 1 auto;
		height: 30px;
		overflow: hidden; // 配合内部滚动使用
	}

	.nav-items {
		display: flex;
		width: 100%;
		height: 100%;
		transition: transform 0.3s ease; // 平滑滚动动画
	}

	.drag_window {
		display: flex;
		align-items: center;
		height: 30px;
		border-radius: 4px 4px 0 0;
		// transition: background-color 0.2s ease;
		.drag-content {
			position: relative;
			display: flex;
			align-items: center;
			gap: 16px;
			border-radius: 6px;
			height: 26px;
			margin: 0 2px;

			.drag_title {
				display: inline-block;
				padding-left: 12px;
				font-size: 13px;
				line-height: 15px;
				white-space: nowrap;
				overflow: hidden;
				text-overflow: ellipsis;
			}

			.drag_close {
				display: flex;
				align-items: center;
				justify-content: center;
				width: 18px;
				height: 18px;
				border-radius: 100%;
				margin-right: 8px;
				&:hover {
					background-color: var(--color-info-300);
				}
			}
		}
	}
	.drag_window.isActive {
		border-top: 2px solid var(--color-primary-500);
		background-color: var(--color-background);
	}
	.drag_window:not(.isActive) {
		.drag-content:hover {
			background-color: var(--color-fill);
		}
	}
	.boder-item {
		padding: 6px 0;
		width: 1px;
		height: 100%;
		display: flex;
		justify-content: center; /* 水平居中 */
	}
	.hiddenLine {
		visibility: hidden;
	}
	.rcMenu-container {
		position: absolute;
	}
	.rcNavMenu {
		background-color: var(--color-page);
		line-height: 32px;
		.menuList {
			font-size: 13px;
			border-radius: 5px;
			padding: 0 10px;
			cursor: pointer;
			&:hover {
				background-color: var(--color-fill);
			}
			div {
				width: 100%;
			}
		}
	}
	li {
		display: inline-flex;
		gap: 5px;
		height: 32px;
		line-height: 32px;
		width: 100%;
		div {
			display: inline-flex;
		}
		.divider--vertical {
			padding: 5px 0;
		}
	}
</style>
